"""
Twitter发布器
"""

import requests
import json
from typing import Dict, Any, Optional
import base64
import hmac
import hashlib
import time
import urllib.parse

from .base import BasePublisher
from ..core.config import get_settings
from ..core.logger import app_logger

settings = get_settings()


class TwitterPublisher(BasePublisher):
    """Twitter发布器"""
    
    def __init__(self):
        self.api_base = "https://api.twitter.com/2"
        self.api_key = settings.TWITTER_API_KEY
        self.api_secret = settings.TWITTER_API_SECRET
        self.access_token = settings.TWITTER_ACCESS_TOKEN
        self.access_token_secret = settings.TWITTER_ACCESS_TOKEN_SECRET
        super().__init__()
    
    def get_platform_name(self) -> str:
        return "Twitter"
    
    def check_configuration(self) -> bool:
        """检查Twitter API配置"""
        required_configs = [
            self.api_key,
            self.api_secret,
            self.access_token,
            self.access_token_secret
        ]
        
        if all(config for config in required_configs):
            app_logger.info("Twitter API配置完整")
            return True
        else:
            app_logger.warning("Twitter API配置不完整，将使用模拟模式")
            return False
    
    async def publish(self, content: str, **kwargs) -> Dict[str, Any]:
        """发布内容到Twitter"""
        
        # 验证内容
        if not self.validate_content(content, max_length=280):
            return self.format_response(False, error="内容验证失败")
        
        try:
            if self.is_configured:
                # 真实API调用
                result = await self._publish_to_twitter_api(content, **kwargs)
            else:
                # 模拟发布
                result = await self._mock_publish(content, **kwargs)
            
            if result["success"]:
                app_logger.info(f"Twitter发布成功: {result.get('data', {}).get('post_id', 'mock_id')}")
            else:
                app_logger.error(f"Twitter发布失败: {result.get('error', '未知错误')}")
            
            return result
            
        except Exception as e:
            app_logger.error(f"Twitter发布异常: {e}")
            return self.format_response(False, error=str(e))
    
    async def _publish_to_twitter_api(self, content: str, **kwargs) -> Dict[str, Any]:
        """调用Twitter API发布内容"""
        
        url = f"{self.api_base}/tweets"
        
        payload = {
            "text": content
        }
        
        # 添加回复支持
        reply_to = kwargs.get("reply_to")
        if reply_to:
            payload["reply"] = {"in_reply_to_tweet_id": reply_to}
        
        try:
            headers = self._get_oauth_headers("POST", url, json.dumps(payload))
            headers["Content-Type"] = "application/json"
            
            response = requests.post(
                url, 
                headers=headers, 
                data=json.dumps(payload),
                timeout=30
            )
            
            if response.status_code == 201:
                data = response.json()
                tweet_data = data.get("data", {})
                return self.format_response(True, {
                    "post_id": tweet_data.get("id", ""),
                    "text": tweet_data.get("text", ""),
                    "url": f"https://twitter.com/user/status/{tweet_data.get('id', '')}"
                })
            else:
                error_data = response.json() if response.content else {}
                error_msg = error_data.get("detail", f"HTTP {response.status_code}")
                return self.format_response(False, error=error_msg)
                
        except Exception as e:
            return self.format_response(False, error=f"API调用失败: {e}")
    
    def _get_oauth_headers(self, method: str, url: str, body: str = "") -> Dict[str, str]:
        """生成OAuth 1.0a认证头"""
        
        # 这里简化了OAuth实现，实际生产环境建议使用tweepy等专业库
        oauth_timestamp = str(int(time.time()))
        oauth_nonce = base64.b64encode(f"{oauth_timestamp}nonce".encode()).decode()
        
        oauth_params = {
            "oauth_consumer_key": self.api_key,
            "oauth_token": self.access_token,
            "oauth_signature_method": "HMAC-SHA1",
            "oauth_timestamp": oauth_timestamp,
            "oauth_nonce": oauth_nonce,
            "oauth_version": "1.0"
        }
        
        # 生成签名
        signature = self._generate_signature(method, url, oauth_params)
        oauth_params["oauth_signature"] = signature
        
        # 构建Authorization头
        auth_header = "OAuth " + ", ".join([
            f'{k}="{urllib.parse.quote(str(v))}"' 
            for k, v in sorted(oauth_params.items())
        ])
        
        return {"Authorization": auth_header}
    
    def _generate_signature(self, method: str, url: str, params: Dict[str, str]) -> str:
        """生成OAuth签名"""
        
        # 参数排序和编码
        sorted_params = sorted(params.items())
        param_string = "&".join([f"{k}={urllib.parse.quote(str(v))}" for k, v in sorted_params])
        
        # 构建签名基字符串
        base_string = f"{method}&{urllib.parse.quote(url)}&{urllib.parse.quote(param_string)}"
        
        # 签名密钥
        signing_key = f"{urllib.parse.quote(self.api_secret)}&{urllib.parse.quote(self.access_token_secret)}"
        
        # 生成HMAC-SHA1签名
        signature = hmac.new(
            signing_key.encode(),
            base_string.encode(),
            hashlib.sha1
        ).digest()
        
        return base64.b64encode(signature).decode()
    
    async def _mock_publish(self, content: str, **kwargs) -> Dict[str, Any]:
        """模拟发布（用于测试）"""
        
        import time
        mock_id = f"tw_{int(time.time())}"
        
        return self.format_response(True, {
            "post_id": mock_id,
            "text": content,
            "url": f"https://twitter.com/mock/status/{mock_id}",
            "note": "这是模拟发布，未实际发送到Twitter"
        })
    
    async def delete_post(self, post_id: str) -> bool:
        """删除推文"""
        
        if not self.is_configured:
            app_logger.info(f"模拟删除推文: {post_id}")
            return True
        
        try:
            url = f"{self.api_base}/tweets/{post_id}"
            headers = self._get_oauth_headers("DELETE", url)
            
            response = requests.delete(url, headers=headers, timeout=30)
            
            if response.status_code == 200:
                app_logger.info(f"推文删除成功: {post_id}")
                return True
            else:
                app_logger.error(f"推文删除失败: HTTP {response.status_code}")
                return False
                
        except Exception as e:
            app_logger.error(f"删除推文异常: {e}")
            return False
    
    async def get_post_status(self, post_id: str) -> Dict[str, Any]:
        """获取推文状态"""
        
        if not self.is_configured:
            return {
                "exists": True,
                "status": "published",
                "note": "模拟状态"
            }
        
        try:
            url = f"{self.api_base}/tweets/{post_id}"
            headers = self._get_oauth_headers("GET", url)
            
            response = requests.get(url, headers=headers, timeout=30)
            
            if response.status_code == 200:
                data = response.json()
                tweet_data = data.get("data", {})
                
                return {
                    "exists": True,
                    "status": "published",
                    "text": tweet_data.get("text", ""),
                    "created_at": tweet_data.get("created_at", ""),
                    "public_metrics": tweet_data.get("public_metrics", {})
                }
            else:
                return {
                    "exists": False,
                    "status": "not_found"
                }
                
        except Exception as e:
            app_logger.error(f"获取推文状态异常: {e}")
            return {
                "exists": False,
                "status": "error",
                "error": str(e)
            }
    
    async def test_connection(self) -> bool:
        """测试Twitter API连接"""
        
        if not self.is_configured:
            return True  # 模拟模式总是可用
        
        try:
            url = f"{self.api_base}/users/me"
            headers = self._get_oauth_headers("GET", url)
            
            response = requests.get(url, headers=headers, timeout=10)
            
            if response.status_code == 200:
                app_logger.info("Twitter API连接测试成功")
                return True
            else:
                app_logger.error(f"Twitter API连接测试失败: HTTP {response.status_code}")
                return False
                
        except Exception as e:
            app_logger.error(f"Twitter API连接测试异常: {e}")
            return False